﻿using Furious.Data;
using Lonntec.UI.PrintSetting;

namespace Lonntec.DevClient
{
    using DevExpress.LookAndFeel;
    using DevExpress.Skins;
    using DevExpress.UserSkins;
    using DevExpress.XtraEditors;
    using Furious;
    using Furious.Authentication;
    using Furious.Common;
    using Furious.Communication;
    using Furious.Proxys;
    using log4net;
    using Lonntec.AsGoodAsItGets;
    using Lonntec.Business;
    using Lonntec.Common;
    using Lonntec.DevClient.Properties;
    using Lonntec.UI;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using NUnit.Framework;
    using System;
    using System.Configuration;
    using System.Data;
    using System.Threading;
    using System.Windows.Forms;

    [TestFixture]
    public class ApplicationRun : IDisposable
    {
        private readonly string[] _args;
        private readonly IUnityContainer container = new UnityContainer();
        private bool isDisposing;
        private readonly ILog logger = LogManager.GetLogger(typeof(ApplicationRun));

        public ApplicationRun(string[] args)
        {
            this._args = args;
        }

        private void CanTryAgain(Exception exception, ref bool canAgain)
        {
            try
            {
                canAgain = LtMessageBox.MessageRetry(MessageRes.ApplicationRun_ConnServerTryAgain, new object[] { exception.Message });
            }
            catch (Exception exception2)
            {
                this.logger.Error(exception2);
                throw;
            }
        }

        public void Dispose()
        {
            if (!this.isDisposing)
            {
                lock (this)
                {
                    if (!this.isDisposing)
                    {
                        this.isDisposing = true;
                        this.Stop();
                    }
                }
            }
        }

        private static void OnResponseException(Exception exception, ref bool tryAgain)
        {
            if (Global.Instance["MainForm"] != null)
            {
                if (exception is InvalidSessionException)
                {
                    if (Global.Instance.ContainsKey("Passport"))
                    {
                        Passport passport = (Passport) Global.Instance["Passport"];
                        ISessionManager manager = Global.Instance.ContainerAdapter.Resolve<IProxyFactory>().ResolveProxy<ISessionManager>();
                        try
                        {
                            Passport passport2 = manager.Login(passport.AuthInfo);
                            Global.Instance["Passport"] = passport2;
                            Global.Instance["Session"] = passport2.Session;
                            tryAgain = true;
                        }
                        catch (Exception)
                        {
                            tryAgain = new LoginForm().ShowDialog() == DialogResult.OK;
                        }
                    }
                }
                else
                {
                    tryAgain = false;
                }
            }
        }

        private static void ReadConfiguration(string configName, IUnityContainer container)
        {
            ExeConfigurationFileMap map2 = new ExeConfigurationFileMap();
            map2.ExeConfigFilename = configName;
            ExeConfigurationFileMap fileMap = map2;
            UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None).GetSection("unity");
            foreach (object obj2 in section.Containers)
            {
                ((UnityContainerElement) obj2).Configure(container);
            }
        }

        private static void SetDevexpressSkin()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            OfficeSkins.Register();
            XtraMessageBox.AllowCustomLookAndFeel = true;
            UserLookAndFeel.Default.SkinName = "Office 2007 Blue";
            SkinManager.EnableFormSkinsIfNotVista();
            SkinManager.EnableMdiFormSkins();
        }

        private void SocketProxyOnConnectError(Exception exception, ref bool tryAgain)
        {
            try
            {
                if (Global.Instance["MainForm"] != null)
                {
                    Form form = (Form)Global.Instance["MainForm"];
                    bool canAgain = false;
                    form.Invoke(new ThreadStart(delegate
                    {
                        this.CanTryAgain(exception, ref canAgain);
                    }));
                    tryAgain = canAgain;
                }
                else
                {
                    this.CanTryAgain(exception, ref tryAgain);
                }
                if (!tryAgain)
                {
                    Application.Exit();
                }
            }
            finally
            {
                Thread.EndCriticalRegion();
            }
        }

        [STAThread, Test]
        public void Start()
        {
            LogManager.GetCurrentLoggers();
            try
            {
                ThreadStart threadStart = delegate
                {
                    Global.Instance.PythonEngine.CreateScope();
                };
                new Thread(threadStart).Start();
                SetDevexpressSkin();
                SerializationTypeBuilder.Instance.CreateSerializationTypes();
                Global.Instance["Icon"] = Resources.SUF;
                this.container.RegisterType<IContainerAdapter, UnityContainerAdapter>(this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IStreamUtility, StreamUtility>(this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IFormatter, BasicFormatter>("BasicFormatter", this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IFormatter, GZipFormatter>("GZipFormatter", this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IFormatter, PlusFormatter>("PlusFormatter", this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IContextInfoFactory, SessionContextFactory>(this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<ILookup, Lookup>(new InjectionMember[0]);
                this.container.RegisterType<IProxyFactory, ProxyFactory>(this.Singleton, new InjectionMember[] { new InjectionConstructor(new object[] { new ResolvedParameter(typeof(ICallHandlerFactory)) }) });
                this.container.RegisterType<ICallHandlerFactory, RemoteCallHandlerFactory>(this.Singleton, new InjectionMember[] { new InjectionConstructor(new object[] { new ResolvedParameter(typeof(IContainerAdapter)) }) });
                this.container.RegisterType<IRemoteInvoke, RemoteInvoke>(this.Singleton, new InjectionMember[] { new InjectionConstructor(new object[] { new ResolvedParameter(typeof(IServicePortal)), typeof(IContainerAdapter) }) });
                this.container.RegisterInstance<SessionOnlineTimer>(new SessionOnlineTimer(), this.Singleton);
                this.container.RegisterType<IHelper, Helper>(this.Singleton, new InjectionMember[0]);
                this.container.RegisterType<IFunctional, ImageSourceForm>("Func_Icons", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, AccountManagerForm>("Func_Accounts", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, RoleManagerForm>("Func_Roles", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, UserManagerForm>("Func_Users", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, SourceTableForm>("Func_Metadata", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, FunctionalTreeForm>("Func_FuncTree", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, SchemaTemplateForm>("Func_SchemaTemplate", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, LogicalTableForm>("Func_MetadataLogical", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, SmartSourceForm>("Func_MetadataSmartSource", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, DbInfoForm>("Func_DbInfo", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, SqlScriptForm>("Func_SqlScript", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, SqlScriptClientForm>("Func_SqlScriptClient", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, CommReportForm>("Func_ReportTemplate", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, CodeRuleForm>("Func_CodeRule", new InjectionMember[0]);
                this.container.RegisterType<IFunctional, PrintSettingForm>("Func_PrintSetting", new InjectionMember[0]);
                ReadConfiguration("Core.config", this.container);
                new BusinessSerializer();
                IContainerAdapter adapter = this.container.Resolve<IContainerAdapter>();
                Global.Instance.ContainerAdapter = adapter;
                Global.Instance.UnityContainer = this.container;
                Global.Instance["ApplicationTitle"] = string.Format("{0} - [{1}]", Constants.ApplicationFullTitle, Resources.AppRunSubTitle);
                foreach (string str in this._args)
                {
                    if (string.Equals("-kis", str, StringComparison.InvariantCultureIgnoreCase))
                    {
                        Global.Instance["DevLoginBackground"] = Resources.DevLoginBackground;
                        Global.Instance["ApplicationTitle"] = "SUF7 for 金蝶 KIS 旗舰版 - 7.0.1.2886";
                    }
                }
                Global.Instance["ProgramType"] = ClientProgramType.RunTimeDesign;
                SocketProxy proxy = this.container.Resolve<SocketProxy>();
                proxy.OnConnectError += new ExceptionEventHandler(this.SocketProxyOnConnectError);
                this.container.Resolve<IRemoteInvoke>().OnResponseException += new ExceptionEventHandler(ApplicationRun.OnResponseException);
                LoginForm form = new LoginForm();
                if (form.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        foreach (DataRow row in this.container.Resolve<IProxyFactory>().ResolveProxy<ISingleDbAccess>().ExecuteTable("SELECT FRowID, FFullTypeName FROM T_LoadAdapter", new object[0]).Rows)
                        {
                            if (System.Type.GetType((string) row["FFullTypeName"]) != null)
                            {
                                this.container.RegisterType(typeof(ILoadAdapter), System.Type.GetType((string) row["FFullTypeName"]), ((Guid) row["FRowID"]).ToString(), this.Singleton, new InjectionMember[0]);
                            }
                        }
                        Application.Run(new MainForm());
                        proxy.OnConnectError -= new ExceptionEventHandler(this.SocketProxyOnConnectError);
                    }
                    finally
                    {
                        if (Global.Instance["Passport"] != null)
                        {
                            try
                            {
                                this.container.Resolve<IProxyFactory>().ResolveProxy<ISessionManager>().Logout(((Passport) Global.Instance["Passport"]).PassportId);
                            }
                            catch (Exception exception)
                            {
                                this.logger.Error(exception);
                            }
                        }
                    }
                }
            }
            catch (Exception exception2)
            {
                this.logger.Error(exception2);
                throw;
            }
        }

        [TearDown]
        public void Stop()
        {
            this.container.Dispose();
        }

        public IUnityContainer Container
        {
            get
            {
                return this.container;
            }
        }

        public LifetimeManager Singleton
        {
            get
            {
                return new ContainerControlledLifetimeManager();
            }
        }
    }
}

